package licode.unisop.auth.application.executor;

import licode.unisop.auth.client.info.UserIdFindIn;
import licode.unisop.auth.exception.AuthErrorCode;
import licode.unisop.oidc.auth.api.OidcSession;
import licode.unisop.oidc.auth.modal.AccessTokenId;
import licode.unisop.oidc.auth.modal.AuthorDetail;
import licode.unisop.oidc.auth.modal.SessionDetail;
import licode.unisop.oidc.auth.modal.UserInfoId;
import licode.unisop.oidc.auth.stu.AuthorUtil;
import licode.unisop.platform.client.api.SiPlatformQueryService;
import licode.unisop.provider.conf.SiAssetType;
import licode.unisop.provider.info.PlatPageInfo;
import licode.unisop.provider.info.SiAssetCodeQueryIn;
import licode.unisop.provider.vo.SiAssetBrief;
import licode.unisop.provider.vo.SiPlatform;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 用户会话操作类
 *
 * @author licode
 */
@Service
public class SessionExecutor {
    @Resource
    private SiPlatformQueryService siPlatformQueryService;

    public SessionDetail getSessionInfo(String token) {
        if (null == token) {
            throw AuthErrorCode.INVALID_ACCESS_TOKEN.buildThrow();
        }
        OidcSession session = AuthorUtil.getSession(AccessTokenId.build(token));
        if (null == session) {
            throw AuthErrorCode.USER_IS_NOT_LOGIN.buildThrow();
        }
        return handleAuthDetail(session.getLoginInfo());
    }

    public SessionDetail getSessionInfoByUser(UserIdFindIn infoId) {
        OidcSession session = AuthorUtil.getSession(UserInfoId.build(infoId.getRealmId(), infoId.getUserId()));
        if (null == session) {
            throw AuthErrorCode.USER_IS_NOT_LOGIN.buildThrow();
        }
        return handleAuthDetail(session.getLoginInfo());
    }

    public SessionDetail handleAuthDetail(SessionDetail details) {
        if (null != details && details.getDetails() != null) {
            fillAuthorPageInfo(details.getDetails());
            fillAuthorClientInfo(details.getDetails());
        }
        return details;
    }

    private void fillAuthorClientInfo(List<AuthorDetail> details) {
        details.forEach(item -> {
            List<SiAssetBrief> assets;
            assets = siPlatformQueryService.queryAssetsByCode(SiAssetCodeQueryIn.builder()
                    .platformId(item.getPlatformId())
                    .assetType(SiAssetType.AT_CLIENT)
                    .build());
            if (null != assets) {
                for (SiAssetBrief asset: assets) {
                    if (asset.getCode().equals(item.getClientId())) {
                        item.setClientName(asset.getName());
                        break;
                    }
                }
            }
        });
    }

    private void fillAuthorPageInfo(List<AuthorDetail> details) {
        List<String> platIds = details.stream().map(AuthorDetail::getPlatformId)
                .distinct().collect(Collectors.toList());
        List<SiPlatform> plats = siPlatformQueryService.findPlatformPage(PlatPageInfo.builder()
                .current(1)
                .pageSize(platIds.size())
                .platformIds(platIds)
                .build()).getData();
        if (null != plats) {
            Map<String, SiPlatform> mapPlat;
            mapPlat = plats.stream().collect(Collectors.toMap(SiPlatform::getId, Function.identity()));
            details.forEach(item -> {
                SiPlatform platform = mapPlat.get(item.getPlatformId());
                if (null != platform) {
                    item.setPlatformName(platform.getName());
                } else {
                    item.setPlatformName("--");
                }
            });
        }
    }
}
